package com.zlyx.easy.core.utils;

/**
 * 
 * Cron表达式生成工具
 *
 */
public class CronUtils {

	/**
	 * 执行方式
	 *
	 */
	public enum ExecuteType {
		EveryDay, EveryWeek, EveryMonth;
	}

	public static class DayCron extends BaseCron {

		public DayCron(Integer hour, Integer minute, Integer second) {
			super(ExecuteType.EveryDay, hour, minute, second);
		}

		public static String cron(Integer hour, Integer minute, Integer second) {
			return new DayCron(hour, minute, second).toString();
		}

	}

	public static class WeekCron extends BaseCron {

		public WeekCron(Integer hour, Integer minute, Integer second) {
			super(ExecuteType.EveryWeek, hour, minute, second);
		}

		/**
		 * 一周的哪几天
		 */
		public String day(Integer... dayOfWeeks) {
			this.dayOfWeeks = dayOfWeeks;
			return toString();
		}

		public static WeekCron cron() {
			return cron(0, 0, 0);
		}

		public static WeekCron cron(Integer hour, Integer minute, Integer second) {
			return new WeekCron(hour, minute, second);
		}
	}

	public static class MonthCron extends BaseCron {

		public MonthCron(Integer hour, Integer minute, Integer second) {
			super(ExecuteType.EveryMonth, hour, minute, second);
		}

		/**
		 * 一个月的哪几天
		 */
		public String day(Integer... dayOfMonths) {
			this.dayOfMonths = dayOfMonths;
			return toString();
		}

		public static MonthCron cron() {
			return cron(0, 0, 0);
		}

		public static MonthCron cron(Integer hour, Integer minute, Integer second) {
			return new MonthCron(hour, minute, second);
		}

	}

	/**
	 * 表达式
	 */
	public static class BaseCron {

		/**
		 * 表达式
		 */
		private StringBuffer cronExp;

		/***
		 * 描述
		 */
		private StringBuffer description;

		/**
		 * 执行间隔
		 */
		ExecuteType executeType;

		/**
		 * 一周的哪几天
		 */
		Integer[] dayOfWeeks;

		/**
		 * 一个月的哪几天
		 */
		Integer[] dayOfMonths;

		/** 秒 */
		Integer second = 0;

		/** 分 */
		Integer minute = 0;

		/** 时 */
		Integer hour = 0;

		/**
		 * 执行间隔
		 * 
		 * @param executeType
		 */
		private BaseCron(ExecuteType executeType, Integer hour, Integer minute, Integer second) {
			this.executeType = executeType;
			this.second = second;
			this.minute = minute;
			this.hour = hour;
		}

		/**
		 * 
		 * 构建Cron表达式
		 * 
		 * @param taskScheduleModel
		 * @return String
		 */
		private String cronExp() {
			cronExp = new StringBuffer("");
			cronExp.append(second).append(" ");// 秒
			cronExp.append(minute).append(" "); // 分
			cronExp.append(hour).append(" "); // 小时
			if (executeType == ExecuteType.EveryDay) {
				cronExp.append("* ");// 日
				cronExp.append("* ");// 月
				cronExp.append("?");// 周
			} else if (executeType == ExecuteType.EveryWeek) {
				cronExp.append("? ");// 一个月中第几天
				cronExp.append("* ");// 月份
				// 周
				for (int i = 0; i < dayOfWeeks.length; i++) {
					if (i == 0) {
						cronExp.append(dayOfWeeks[i]);
					} else {
						cronExp.append(",").append(dayOfWeeks[i]);
					}
				}
			} else if (executeType == ExecuteType.EveryMonth) {
				for (int i = 0; i < dayOfMonths.length; i++) {
					if (i == 0) {
						cronExp.append(dayOfMonths[i]);
					} else {
						cronExp.append(",").append(dayOfMonths[i]);
					}
				}
				cronExp.append(" * ");// 月份
				cronExp.append("?");// 周
			}
			return cronExp.toString();
		}

		/**
		 * 表达式描述
		 * 
		 * @return
		 */
		private String description() {
			description = new StringBuffer("");
			if (executeType == ExecuteType.EveryDay) {
				description.append("每天");
				description.append(hour).append("时");
				description.append(minute).append("分");
				description.append(second).append("秒");
				description.append("执行");
			} else if (executeType == ExecuteType.EveryWeek) {
				if (dayOfWeeks != null && dayOfWeeks.length > 0) {
					String days = "";
					for (int i : dayOfWeeks) {
						days += "周" + i;
					}
					description.append("每周的").append(days);
				}
				description.append(" ");
				description.append(hour).append("时");
				description.append(minute).append("分");
				description.append(second).append("秒");
				description.append("执行");
			} else if (executeType == ExecuteType.EveryMonth) {
				if (dayOfMonths != null && dayOfMonths.length > 0) {
					String days = "";
					for (int i : dayOfMonths) {
						days += i + "号";
					}
					description.append("每月的").append(days).append(" ");
				}
				description.append(hour).append("时");
				description.append(minute).append("分");
				description.append(second).append("秒");
				description.append("执行");
			}
			return description.toString();
		}

		public String build() throws Exception {
			if (cronExp == null || cronExp.length() == 0) {
				if (hour < 0 || hour > 23) {
					throw new Exception("小时值必须在0~23之间");
				}
				if (minute < 0 || minute > 59) {
					throw new Exception("分钟值必须在0~59之间");
				}
				if (second < 0 || second > 59) {
					throw new Exception("秒值必须在0~59之间");
				}
				System.out.println(cronExp());// 生成表达式
				System.out.println(description()); // 生成描述
			}
			return cronExp.toString();
		}

		public String toString() {
			try {
				return build();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}

}